package com.x52im.rainbowchat.http.logic.pay.alipay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.BaseConf;
import com.x52im.rainbowchat.http.logic.dto.AccountDTO;
import com.x52im.rainbowchat.http.logic.dto.AlipayCashDTO;
import com.x52im.rainbowchat.http.logic.pay.redenvelope.GenSubEnvelope;
import org.apache.commons.lang.StringUtils;

import java.math.BigDecimal;
import java.util.Map;
import java.util.Vector;

public class MCash {
    DBShell db = new DBShell();

    public String transfer(AlipayCashDTO dto) throws Exception {
        Map<String, Object> user = db.queryDataMap("select pay_psw, is_realname from missu_users where user_uid=" + dto.getUserUid());
        String is_realname = (String) user.get("is_realname");
        if (is_realname == null || !is_realname.equals("T")) {
            return "请实名认证后再提现";
        }

        if (CommonUtils.isStringEmpty(dto.getPayPsw())) {
            return "提现必须输入支付密码";
        }

        String pay_psw = (String) user.get("pay_psw");
        if (CommonUtils.isStringEmpty(pay_psw)) {
            return "支付密码为空，请先设置支付密码";
        }

        String payPswDTO = CommonUtils.encyptPassword(dto.getPayPsw(), "");
        if (!payPswDTO.equals(pay_psw)) {
            return "支付密码不一致";
        }

        String cashLimitStr = BaseConf.getInstance().getALI_CASH_LIMIT();
        Integer cashLimit = CommonUtils.isStringEmpty(cashLimitStr) ? 1000 : Integer.parseInt(cashLimitStr);
        Integer totalTrans = Integer.parseInt(dto.getTransAmount());    // 分
        if (totalTrans < cashLimit) {  // 提现必须大于等于10元
            return "提现金额不能低于" + (cashLimit / 100) + "元";
        }

        Map<String, Object> account = db.queryDataMap("select total, alipay_user_id from missu_account where user_uid=" + dto.getUserUid());
        String _totalAccount = (String) account.get("total");
        Integer totalAccount = Integer.parseInt(_totalAccount);
        if (totalAccount < totalTrans) {
            return "账户余额不足,不能提现";
        }
        Integer totalNew = totalAccount - totalTrans;

        // 实际提现额度减去0.0006%
        String actualAmountFen = getActualTransAmount(dto); // 和支付宝交互的额度,分,已扣减手续费
        String actualAmountYuan = GenSubEnvelope.fenToYuan(actualAmountFen);    // 和支付宝交互的额度,元,已扣减手续费

        String alipayUserId = (String) account.get("alipay_user_id");
        dto.setProductCode("TRANS_ACCOUNT_NO_PWD");
        dto.setBizScene("DIRECT_TRANSFER");
        dto.setIdentityType("ALIPAY_USER_ID");
        dto.setIdentity(alipayUserId);
        dto.setOrderTitle("聊讯APP提现");
        dto.setBusinessParams("{'payer_show_name_use_alias':'true'}");
        dto.setOutBizNo(AlipayClientTools.getOutBizNo(String.valueOf(dto.getUserUid())));

        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        model.setOutBizNo(dto.getOutBizNo());
        model.setRemark(dto.getOrderTitle());
        model.setBusinessParams(dto.getBusinessParams());
        model.setBizScene(dto.getBizScene());
        Participant payeeInfo = new Participant();
        payeeInfo.setIdentity(alipayUserId);
        payeeInfo.setIdentityType(dto.getIdentityType());
        model.setPayeeInfo(payeeInfo);
        model.setTransAmount(actualAmountYuan);
        model.setProductCode(dto.getProductCode());
        model.setOrderTitle(dto.getOrderTitle());
        request.setBizModel(model);
        AlipayFundTransUniTransferResponse response = AlipayClientTools.alipayClient.certificateExecute(request);

        if (!response.getCode().equalsIgnoreCase("10000")) {
            return JSON.toJSONString(response);
        }

        Vector sqls = new Vector();
        Vector values = new Vector();

        String sql = "INSERT INTO alipay_cash" +
                "(alipay_user_id, user_uid, out_biz_no, trans_amount, " +
                "product_code, biz_scene, identity_type, `identity`, " +
                "name, order_title, remark, business_params, " +
                "order_id, pay_fund_order_id, status, trans_date, code, req_xml, resp_xml, create_date, trans_amount_all)" +
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), ?)";
        sqls.add(sql);
        values.add(new Object[]{
                dto.getIdentity(), dto.getUserUid(), dto.getOutBizNo(), actualAmountYuan,
                dto.getProductCode(), dto.getBizScene(), dto.getIdentityType(), dto.getIdentity(),
                dto.getName(), dto.getOrderTitle(), dto.getRemark(), dto.getBusinessParams(),
                response.getOrderId(), response.getPayFundOrderId(), response.getStatus(), response.getTransDate(),
                response.getCode(), JSON.toJSONString(request), JSON.toJSONString(response), GenSubEnvelope.fenToYuan(dto.getTransAmount())
        });
        boolean a = db.update(sqls, values, true);

        if (a) {
            sqls.clear();
            values.clear();

            String id = db.querySingleItem("id", "alipay_cash", "out_biz_no='" + dto.getOutBizNo() + "'");

            // 更新账户
            String sql3 = "UPDATE missu_account SET total=? WHERE user_uid=?";
            sqls.add(sql3);
            values.add(new Object[]{totalNew, dto.getUserUid()});

            // 插入账户历史表
            sqls.add("INSERT INTO missu_account_his(user_uid,total,`type`,type_id,change_amount) VALUES(?,?,?,?,?)");
            values.add(new Object[]{dto.getUserUid(), totalNew, AccountDTO.TYPE_FOR_CASH, id, dto.getTransAmount()});

            boolean b = db.update(sqls, values, true);
            LoggerFactory.getLog().info(String.format("提现完成,%s,%s,%s", dto.getUserUid(), id, b));
        }

        return JSON.toJSONString(response);
    }

    /**
     * 支付宝规定,充值的时候实际扣掉了6‰的手续费,也就是充值1000,其实我们只是到账994<br>
     * 因此提现的时候要扣除6‰,提现1000我们只能给他们994
     *
     * @param dto
     */
    private String getActualTransAmount(AlipayCashDTO dto) {
        String cashRate = BaseConf.getInstance().getALI_CASH_RATE();
        if (StringUtils.isEmpty(cashRate)) {
            cashRate = "0.994";
        }

        String transAmount = dto.getTransAmount();  // 分
        double dt = Double.parseDouble(transAmount);
        double x = dt * Float.parseFloat(cashRate);  // 直接算最后结果
        BigDecimal bigDecimal = new BigDecimal(x);
        bigDecimal.setScale(0, BigDecimal.ROUND_DOWN);
        int lastFen = bigDecimal.intValue();
        return String.valueOf(lastFen);

        // 采用直接舍弃的方式
//        BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_DOWN);
//        System.out.println(c);//2.22
    }
}
